/**
 * 实现文件系统子服务
 */

#ifndef FILE_SERVER_FILE_SERVER_H
#define FILE_SERVER_FILE_SERVER_H

#include <brpc/server.h>
#include <butil/logging.h>

#include <memory>

#include "base.pb.h"
#include "etcd.h"
#include "file.pb.h"

namespace chat {
class FileServerImpl : public FileService {
   public:
    FileServerImpl(const std::string& file_storage_path)
        : file_storage_path_(file_storage_path) {
        if (file_storage_path_.back() != '/') {
            file_storage_path_ += "/";
        }
    }

    /**
     * @brief 根据 file_storage_path_, 创建存储目录
     */
    bool createStoragePath();

    void GetSingleFile(::google::protobuf::RpcController* controller,
                       const ::chat::GetSingleFileReq* request,
                       ::chat::GetSingleFileRsp* response,
                       ::google::protobuf::Closure* done);

    void GetMultiFile(::google::protobuf::RpcController* controller,
                      const ::chat::GetMultiFileReq* request,
                      ::chat::GetMultiFileRsp* response,
                      ::google::protobuf::Closure* done);

    void PutSingleFile(::google::protobuf::RpcController* controller,
                       const ::chat::PutSingleFileReq* request,
                       ::chat::PutSingleFileRsp* response,
                       ::google::protobuf::Closure* done);

    void PutMultiFile(::google::protobuf::RpcController* controller,
                      const ::chat::PutMultiFileReq* request,
                      ::chat::PutMultiFileRsp* response,
                      ::google::protobuf::Closure* done);

   private:
    std::string file_storage_path_;  // 文件存储路径
};

class FileServer {
   public:
    FileServer(const RegistryPtr& register_client,
               const std::shared_ptr<brpc::Server> brpc_server)
        : register_client_(register_client), brpc_server_(brpc_server) {}

    /**
     * @brief 启动rpc服务
     */
    void start();

   private:
    RegistryPtr register_client_ = nullptr;
    std::shared_ptr<brpc::Server> brpc_server_ = nullptr;
};

using FileServerPtr = std::shared_ptr<FileServer>;

class FileServerBuilder {
   public:
    /**
     * @brief 创建服务注册客户端
     * @param register_name[in]: 服务名称
     * @param etcd_host[in]: etcd服务器 ip:port
     * @param access_host[in]: 外部访问 ip:port
     */
    void makeRegisterClient(const std::string& register_name,
                            const std::string& etcd_host,
                            const std::string& access_host);

    /**
     * @brief 创建 brpc 服务
     * @param port[in]: brpc 服务器端口
     * @param idle_timeout_sec[in]: 连接空闲超时时间，超时后连接关闭
     * @param num_threads[in]: 线程数量
     * @param file_storage_path[in]: 文件存储路径
     */
    void makeBrpcServer(const uint16_t port, const int idle_timeout_sec,
                        const int num_threads,
                        const std::string file_storage_path);

    /**
     * @brief 构造一个 ASRServer对象 并返回
     */
    FileServerPtr build();

   private:
    RegistryPtr register_client_ = nullptr;
    std::shared_ptr<brpc::Server> brpc_server_ = nullptr;
};
}  // namespace chat

#endif  // FILE_SERVER_FILE_SERVER_H